<?php
namespace App\Components\Admin;

use App\Components\Redis;
use Console\Supports\Helper;

class Router
{
    // URL前缀标识
    const URL_PREFIX = '/admin';

    /**
     * 获取当前请求匹配到的 管理后台控制器 ，及其方法名
     */
    public static function getCurrentRequestControllerInfo(): array
    {
        if (!isset($_SERVER['REQUEST_URI']) ||
            strpos($_SERVER['REQUEST_URI'], self::URL_PREFIX) !== 0
        ) {
            return [];
        }

        // 获取请求路径
        $uriPattern = $_SERVER['REQUEST_URI'];
        if (strpos($uriPattern, '?') === false) {
        } else {
            $uriPattern = substr($uriPattern, 0, strpos($uriPattern, '?'));
        }

        $cacheKey = 'COM:ADMIN:ROUTER:GCRCI:' . $uriPattern;
        $cacheRs = Redis::get($cacheKey);
        if ($cacheRs !== false && $cacheRs !== null) {
            return json_decode($cacheRs, true);
        }

        // 路径中抽出方法名
        $functionName = substr($uriPattern, strrpos($uriPattern, '/') + 1);
        $functionName = array_map(function ($v) {
            return ucfirst($v);
        }, explode('-', $functionName));
        $functionName = lcfirst(implode('', $functionName));

        // 路径中解出类名
        $className = substr($uriPattern, strlen(self::URL_PREFIX));
        $className = substr($className, 0, strrpos($className, '/'));
        $className = Node::CTL_NAMESPACE_PREFIX . $className;
        list($className, $namespace) = Helper::generateFilePath($className, '', false);
        $classFile = ltrim($namespace, '\\') . '\\' . $className . 'Controller';
        unset($className, $namespace);
        if (class_exists($classFile) !== true) {
            return [];
        }

        $classMethod = get_class_methods($classFile);
        if ($classMethod === null || !is_array($classMethod) ||
            !in_array($functionName, $classMethod)
        ) {
            return [];
        }
        unset($classMethod);

        Redis::setex($cacheKey, Redis::tinyTime(3), json_encode([$uriPattern, $classFile, $functionName]));

        return [$uriPattern, $classFile, $functionName];
    }

    /**
     * 根据控制器和方法名，转成URL
     */
    public static function ControllerToUriPath(string $controller, string $functionName): string
    {
        if (strpos($controller, Node::CTL_NAMESPACE_PREFIX) !== 0) {
            return '';
        }

        $controller = str_replace(Node::CTL_NAMESPACE_PREFIX, self::URL_PREFIX, $controller);
        $controller = array_map(function ($v) {
            return lcfirst($v);
        }, explode('\\', $controller));
        $level = count($controller);
        $level -= 1;
        if (strpos($controller[$level], 'Controller') === false) {
            return '';
        }
        $controller[$level] = substr($controller[$level], 0, strpos($controller[$level], 'Controller'));
        unset($level);

        foreach ($controller as $k1 => $v1) {
            $temp = preg_split("/(?=[A-Z])/", $v1);
            if (!isset($temp[1])) {
                continue;
            }

            foreach ($temp as $k2 => $v2) {
                $temp[$k2] = lcfirst($v2);
            }
            $controller[$k1] = implode('-', $temp);
        }
        $controller = implode('/', $controller);

        return $controller . '/' . $functionName;
    }
}
